package net.lgy.apitest.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.hc.client5.http.classic.methods.HttpDelete;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpPut;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.net.URIBuilder;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * API测试工具类
 */
@Component
public class ApiTestUtils {

    /**
     * 发送HTTP请求
     * @param url 请求URL
     * @param method 请求方法
     * @param headers 请求头
     * @param params 请求参数（GET方法使用）
     * @param body 请求体（POST/PUT方法使用）
     * @return 响应结果
     */
    public ApiTestResponse sendRequest(String url, String method, String headers, String params, String body) {
        ApiTestResponse response = new ApiTestResponse();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpUriRequestBase httpRequest = null;
        long startTime = System.currentTimeMillis();

        try {
            // 构建请求对象
            httpRequest = buildHttpRequest(url, method, params, body);
            
            // 设置请求头
            if (headers != null && !headers.isEmpty()) {
                Map<String, String> headerMap = parseHeaders(headers);
                for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                    httpRequest.addHeader(entry.getKey(), entry.getValue());
                }
            }
            
            // 设置默认Content-Type
            if (!httpRequest.containsHeader("Content-Type") && ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method))) {
                httpRequest.addHeader("Content-Type", "application/json; charset=utf-8");
            }
            
            // 发送请求
            CloseableHttpResponse httpResponse = httpClient.execute(httpRequest);
            long endTime = System.currentTimeMillis();
            
            // 处理响应
            response.setStatusCode(httpResponse.getCode());
            response.setResponseTime((int) (endTime - startTime));
            
            // 获取响应头
            org.apache.hc.core5.http.Header[] responseHeaders = httpResponse.getHeaders();
            Map<String, String> responseHeaderMap = new HashMap<>();
            for (org.apache.hc.core5.http.Header header : responseHeaders) {
                responseHeaderMap.put(header.getName(), header.getValue());
            }
            response.setHeaders(JSON.toJSONString(responseHeaderMap));
            
            // 获取响应体
            String responseBody = EntityUtils.toString(httpResponse.getEntity(), StandardCharsets.UTF_8);
            response.setBody(responseBody);
            
            // 关闭响应
            httpResponse.close();
            
        } catch (Exception e) {
            response.setSuccess(false);
            response.setErrorMessage(e.getMessage());
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                // 忽略关闭异常
            }
        }
        
        return response;
    }
    
    /**
     * 构建HTTP请求对象
     */
    private HttpUriRequestBase buildHttpRequest(String url, String method, String params, String body) throws URISyntaxException, IOException {
        if ("GET".equalsIgnoreCase(method)) {
            return buildGetRequest(url, params);
        } else if ("POST".equalsIgnoreCase(method)) {
            return buildPostRequest(url, body);
        } else if ("PUT".equalsIgnoreCase(method)) {
            return buildPutRequest(url, body);
        } else if ("DELETE".equalsIgnoreCase(method)) {
            return buildDeleteRequest(url);
        } else {
            throw new IllegalArgumentException("不支持的请求方法: " + method);
        }
    }
    
    /**
     * 构建GET请求
     */
    private HttpGet buildGetRequest(String url, String params) throws URISyntaxException {
        URIBuilder uriBuilder = new URIBuilder(url);
        
        if (params != null && !params.isEmpty()) {
            try {
                JSONObject paramJson = JSON.parseObject(params);
                Set<String> keys = paramJson.keySet();
                for (String key : keys) {
                    Object value = paramJson.get(key);
                    if (value != null) {
                        uriBuilder.addParameter(key, value.toString());
                    }
                }
            } catch (Exception e) {
                // 如果params不是有效的JSON，尝试作为普通参数解析
                String[] paramArray = params.split("&");
                for (String param : paramArray) {
                    String[] keyValue = param.split("=", 2);
                    if (keyValue.length == 2) {
                        uriBuilder.addParameter(keyValue[0], keyValue[1]);
                    }
                }
            }
        }
        
        return new HttpGet(uriBuilder.build());
    }
    
    /**
     * 构建POST请求
     */
    private HttpPost buildPostRequest(String url, String body) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        if (body != null && !body.isEmpty()) {
            StringEntity entity = new StringEntity(body, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
        }
        return httpPost;
    }
    
    /**
     * 构建PUT请求
     */
    private HttpPut buildPutRequest(String url, String body) throws IOException {
        HttpPut httpPut = new HttpPut(url);
        if (body != null && !body.isEmpty()) {
            StringEntity entity = new StringEntity(body, ContentType.APPLICATION_JSON);
            httpPut.setEntity(entity);
        }
        return httpPut;
    }
    
    /**
     * 构建DELETE请求
     */
    private HttpDelete buildDeleteRequest(String url) {
        return new HttpDelete(url);
    }
    
    /**
     * 解析请求头字符串为Map
     */
    private Map<String, String> parseHeaders(String headers) {
        Map<String, String> headerMap = new HashMap<>();
        try {
            JSONObject headerJson = JSON.parseObject(headers);
            Set<String> keys = headerJson.keySet();
            for (String key : keys) {
                Object value = headerJson.get(key);
                if (value != null) {
                    headerMap.put(key, value.toString());
                }
            }
        } catch (Exception e) {
            // 如果headers不是有效的JSON，尝试按行解析
            String[] lines = headers.split("\n");
            for (String line : lines) {
                line = line.trim();
                if (!line.isEmpty()) {
                    int colonIndex = line.indexOf(':');
                    if (colonIndex > 0) {
                        String key = line.substring(0, colonIndex).trim();
                        String value = line.substring(colonIndex + 1).trim();
                        headerMap.put(key, value);
                    }
                }
            }
        }
        return headerMap;
    }
    
    /**
     * API测试响应类
     */
    public static class ApiTestResponse {
        private Integer statusCode;
        private String headers;
        private String body;
        private Integer responseTime;
        private Boolean success = true;
        private String errorMessage;
        
        // getter和setter方法
        public Integer getStatusCode() {
            return statusCode;
        }
        
        public void setStatusCode(Integer statusCode) {
            this.statusCode = statusCode;
        }
        
        public String getHeaders() {
            return headers;
        }
        
        public void setHeaders(String headers) {
            this.headers = headers;
        }
        
        public String getBody() {
            return body;
        }
        
        public void setBody(String body) {
            this.body = body;
        }
        
        public Integer getResponseTime() {
            return responseTime;
        }
        
        public void setResponseTime(Integer responseTime) {
            this.responseTime = responseTime;
        }
        
        public Boolean getSuccess() {
            return success;
        }
        
        public void setSuccess(Boolean success) {
            this.success = success;
        }
        
        public String getErrorMessage() {
            return errorMessage;
        }
        
        public void setErrorMessage(String errorMessage) {
            this.errorMessage = errorMessage;
        }
    }
}